package negocio;

import java.awt.Point;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

/**
 * Um inimigo é um alvo que pode ser atingido por uma bala. Possui uma imagem
 * que o representa e pode se mover no cenário.
 * <p>
 * Cada inimigo é uma thread, para que possam haver vários inimigos ao mesmo
 * tempo no cenário.
 */
public abstract class Inimigo extends Thread {

	private BufferedImage image;
	private int x, y; // coordenadas do canto superior
	private int relX, relY; // coordenadas relativas do HotPoint
	private int hotX, hotY; // coordenadas absolutas do HotPoint
	protected final HotSpot hotspot;

	/**
	 * Cria um novo inimigo, sem iniciar sua execução (chamar o método start ou
	 * run) ou mostrá-lo na tela (não é de responsabilidade dessa classe saber
	 * como se exibe a imagem de um inimigo na tela).
	 * 
	 * @param urlImagem
	 *            o endereço do arquivo de imagem que representa esse inimigo
	 * @param hotPoint
	 *            coordenadas da posição relativa entre o hotpoint e o início da
	 *            imagem (canto superior esquerdo)
	 * @param hotspot
	 *            o caminho por onde esse inimigo irá caminhar
	 */
	public Inimigo(String urlImagem, Point hotPoint, HotSpot hotspot) {
		try {
			this.image = ImageIO.read(new File(urlImagem));
		} catch (IOException e) {
			e.printStackTrace();
		}
		this.relX = hotPoint.x;
		this.relY = hotPoint.y;
		this.hotspot = hotspot;
	}

	public BufferedImage getImage() {
		return image;
	}

	protected void setImage(String urlImagem) {
		try {
			this.image = ImageIO.read(new File(urlImagem));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * @return a coordenada x absoluta do hotpoint em relação ao container desse
	 *         inimigo
	 */
	public int getHotX() {
		return hotX;
	}

	/**
	 * Determina a posição x absoluta do hotpoint desse inimigo.
	 */
	public void setHotX(int hotX) {
		this.hotX = hotX;
		this.x = hotX - relX;
	}

	/**
	 * @return a coordenada y absoluta do hotpoint em relação ao container desse
	 *         inimigo
	 */
	public int getHotY() {
		return hotY;
	}

	/**
	 * Determina a posição x absoluta do hotpoint desse inimigo.
	 */
	public void setHotY(int hotY) {
		this.hotY = hotY;
		this.y = hotY - relY;
	}

	/**
	 * @return a posição x relativa entre hotpoint e o início da imagem
	 */
	protected int getRelX() {
		return relX;
	}

	/**
	 * Define um novo valor relativo entre o início da imagem e o seu hotpoint.
	 * Esse método existe para se ajustar o hotpoint caso a imagem mude.
	 */
	protected void setRelX(int relX) {
		this.relX = relX;
	}

	/**
	 * @return a posição y relativa entre hotpoint e o início da imagem
	 */
	protected int getRelY() {
		return relY;
	}

	/**
	 * Define um novo valor relativo entre o início da imagem e o seu hotpoint.
	 * Esse método existe para se ajustar o hotpoint caso a imagem mude.
	 */
	protected void setRelY(int relY) {
		this.relY = relY;
	}

	/**
	 * @return a coordenada x absoluta da posição do início da imagem desse
	 *         inimigo
	 */
	public int getX() {
		return x;
	}

	/**
	 * @return a coordenada y absoluta da posição do início da imagem desse
	 *         inimigo
	 */
	public int getY() {
		return y;
	}

	/**
	 * Informa se esse inimigo foi atingido pelo tiro ou não. A decisão é
	 * baseada no tamanho da imagem e nas coordenadas da imagem e do tiro.
	 * 
	 * @param t
	 *            o tiro que se deseja saber se atingiu esse inimigo
	 * @return true se o inimigo foi atingido, false caso contrário
	 */
	public boolean isAtingido(Tiro t) {
		if (t.x >= x && t.x <= (x + image.getWidth()) && t.y >= y
				&& t.y <= (y + image.getHeight())) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * Executa a animação e todas as operações relacionadas a mostrar que o
	 * inimigo morreu. Também faz com que o inimigo pare de se mexer e atirar.
	 * Porém, esse metódo não torna o inimigo invisível (essa classe nem sabe
	 * que a está pintando), mas encerra a thread.
	 */
	public abstract void morre();

}
